package io.modifier.basic.emo.permission

import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

interface EmoPermissionTip {

    val tipStr: String

    @Composable
    fun AnimatedVisibilityScope.Content()

    val notAvailableStr: String

    @Composable
    fun AnimatedVisibilityScope.NotAvailableContent(req: () -> Unit)

}

class SimpleEmoPermissionTip(private val tip: String, private val notAvailable: String, private val sureStr: String) : EmoPermissionTip {

    override val tipStr: String
        get() = tip

    @OptIn(ExperimentalAnimationApi::class)
    @Composable
    override fun AnimatedVisibilityScope.Content() {
        Box(
            modifier = Modifier
                .windowInsetsPadding(WindowInsets.systemBars)
                .padding(horizontal = 16.dp, vertical = 24.dp)
                .fillMaxWidth()
                .animateEnterExit(
                    slideInVertically(tween(), initialOffsetY = { -it }),
                    slideOutVertically(tween(), targetOffsetY = { -it }),
                )
                .shadow(32.dp, RoundedCornerShape(12.dp), true)
                .background(MaterialTheme.colorScheme.primary)
                .padding(horizontal = 16.dp, vertical = 24.dp),
        ) {
            Text(
                text = tip,
                fontSize = 17.sp,
                color = MaterialTheme.colorScheme.onPrimary,
            )
        }
    }

    override val notAvailableStr: String
        get() = notAvailable

    @OptIn(ExperimentalAnimationApi::class)
    @Composable
    override fun AnimatedVisibilityScope.NotAvailableContent(req: () -> Unit) {
        Box(
            modifier = Modifier
                .windowInsetsPadding(WindowInsets.systemBars)
                .padding(horizontal = 16.dp, vertical = 24.dp)
                .fillMaxWidth()
                .animateEnterExit(
                    slideInVertically(tween(), initialOffsetY = { -it }),
                    slideOutVertically(tween(), targetOffsetY = { -it }),
                )
                .shadow(32.dp, RoundedCornerShape(12.dp), true)
                .background(MaterialTheme.colorScheme.primary)
                .padding(horizontal = 16.dp, vertical = 24.dp),
            contentAlignment = Alignment.Center
        ) {
            Column(horizontalAlignment = Alignment.CenterHorizontally) {
                Text(
                    text = notAvailable,
                    fontSize = 17.sp,
                    color = MaterialTheme.colorScheme.onPrimary,
                )
                Box(modifier = Modifier.height(15.dp))
                Text(
                    text = tip,
                    fontSize = 17.sp,
                    color = MaterialTheme.colorScheme.onPrimary,
                )
                Box(modifier = Modifier.height(15.dp))
                Box(
                    modifier = Modifier
                        .background(MaterialTheme.colorScheme.error)
                        .clickable { req.invoke() }
                        .padding(horizontal = 15.dp, vertical = 8.dp),
                    contentAlignment = Alignment.Center,
                ) {
                    Text(
                        text = sureStr,
                        fontSize = 17.sp,
                        color = MaterialTheme.colorScheme.onError,
                    )
                }
            }
        }
    }
}
